'''
Description: 设备监听模块
Author: HowsenFisher
Date: 2021-04-03 10:57:04
LastEditTime: 2021-04-11 00:31:20
LastEditors: liutq
Reference: 
'''
import socket
from NetTools.ipTools import *
import time
import select as sl
from Config import conf
from sql.DB import *

class DeviceListener:
    '''
    @description: 
    @param  {*}
    @return {*}
    @param {*} self
    @param {*} ip：本机IP地址
    @param {*} mask：本机子网掩码
    '''
    def __init__(self,ip,mask):
        #初始化socket TCP
        self.socketTcp = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 本机IP
        self.ip = ip
        # 本机子网掩码
        self.mask = mask
        # 监听到的设备列表
        self.clientList=[]

    '''
    @description: 扫描子网设备函数
    @param  {*}
    @return {*}
    @param {*} self
    '''
    def scan(self):
        # 本机IP
        ip = self.ip
        # 本机子网掩码
        mask = self.mask
        #初始化socket UDP Mode 用于广播寻找所有设备
        socketUDP = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        socketUDP.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
        # 设置socket非阻塞模式
        socketUDP.setblocking(0)
        # 通过本机IP和子网掩码得到广播地址
        broadcastAddr = generateBroadcastByIPAndMask(ip,mask)
        # 发送广播包
        socketUDP.sendto("broadcast".encode("utf-8"),(broadcastAddr,conf.device_scan_port))
        # 开始计时
        start = time.time()
        while True:
            # 截取时间
            end = time.time()
            # 如果用时大于设备监听超时时间，则退出
            if end - start > conf.deviceListen_timeout:
                break
            print(end-start)
            # 一种延时处理，不用深究
            ready = sl.select([socketUDP], [], [], 1)
            data=b""
            if ready[0]:
                data ,addr = socketUDP.recvfrom(1024)
            # 如果接收到的消息含有here字段，证明找到了设备
            if data.decode("utf-8").split(":")[0] == "here":
                # 将设备信息提取出来写入设备列表
                name = data.decode("utf-8").split(":")[1]
                avatar = data.decode("utf-8").split(":")[2]
                self.clientList.append([name,addr,avatar])
                # 向数据库写入设备信息
                insertDevice(username=name,ip=addr[0])
        return self.clientList

if __name__ == "__main__":
    mySocket = DeviceListener("10.23.178.164","255.255.255.0")
    mySocket.scan()